package com.kakarote.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.kakarote.admin.common.AdminCodeEnum;
import com.kakarote.admin.common.AdminConst;
import com.kakarote.admin.common.AdminModuleEnum;
import com.kakarote.admin.mapper.AdminDataAuthDeptMapper;
import com.kakarote.core.common.enums.AdminRoleTypeEnum;
import com.kakarote.admin.entity.BO.AdminUserBO;
import com.kakarote.admin.entity.BO.AdminUserRoleBO;
import com.kakarote.admin.entity.PO.*;
import com.kakarote.admin.entity.VO.AdminRoleVO;
import com.kakarote.admin.entity.VO.AdminUserVO;
import com.kakarote.admin.mapper.AdminRoleMapper;
import com.kakarote.admin.service.*;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.common.log.enums.ApplyEnum;
import com.kakarote.common.log.enums.OperateObjectEnum;
import com.kakarote.core.common.Const;
import com.kakarote.core.common.cache.AdminCacheKey;
import com.kakarote.core.common.enums.DataAuthEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.exception.CrmException;
import com.kakarote.core.redis.Redis;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.BaseUtil;
import com.kakarote.core.utils.UserCacheUtil;
import com.kakarote.core.utils.UserUtil;
import com.kakarote.hrm.feign.service.HrmService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author zhangzhiwei
 * @since 2020-04-27
 */
@Service
public class AdminRoleServiceImpl extends BaseServiceImpl<AdminRoleMapper, AdminRole> implements IAdminRoleService {

    @Autowired
    private IAdminMenuService adminMenuService;

    @Autowired
    private IAdminConfigService adminConfigService;

    @Autowired
    private IAdminUserRoleService adminUserRoleService;

    @Autowired
    private IAdminRoleMenuService adminRoleMenuService;

    @Autowired
    private IAdminUserService adminUserService;

    @Autowired
    private IAdminDeptService adminDeptService;


    @Autowired
    private IAdminRoleAuthService adminRoleAuthService;

    @Autowired
    private IAdminSubsidiaryDeptService adminSubsidiaryDeptService;

    @Autowired
    private Redis redis;

    @Autowired
    private HrmService hrmService;

    @Autowired
    private IAdminConfigService configService;

    @Autowired
    private IAdminRoleService adminRoleService;

    @Autowired
    private IAdminDeptRoleService adminDeptRoleService;


    @Autowired
    private IAdminDataAuthDeptService adminDataAuthDeptService;

    @Autowired
    private AdminDataAuthDeptMapper adminDataAuthDeptMapper;

    /**
     * 管理员枚举
     */
    private static final String ADMIN_NUM = "adminNum";

    /**
     * 用户枚举
     */
    private static final String USER_NUM = "userNum";

    /**
     * 进销存模块
     */
    private static final String JXC = "jxc";

    /**
     * bi模块
     */
    private static final String BI = "bi";

    /**
     * hrm模块
     */
    private static final String HRM = "hrm";

    private static final String CP = "cp";

    /**
     * 营销管理模块
     */
    private static final String CS = "cs";
    /**
     * WordPress管理模块
     */
    private static final String WP = "wp";

    /**
     * 正则判断
     */
    private static final String CANONICAL = "^[(]\\d+[)]$";

    private static final String LEFT_BRACKET = "(";

    private static final String RIGHT_BRACKET = ")";

    private static final int NUMBER = 935;
    private static final Long WP_NUMBER = 1325L;

    /**
     * 查询用户所属权限
     *
     * @return obj
     */
    @Override
    public JSONObject auth(Long userId) {
        String cacheKey = AdminCacheKey.USER_AUTH_CACHE_KET + UserUtil.getUserId();
        if (redis.exists(cacheKey)) {
            return redis.get(cacheKey);
        }
        List<AdminMenu> adminMenus = adminMenuService.queryMenuList(userId);
        //查询项目管理的用户权限
        List<AdminMenu> adminProjectMenus = adminMenuService.queryProjectUserMenuList(userId).stream().distinct().collect(Collectors.toList());
        adminMenus.addAll(adminProjectMenus);
        List<AdminMenu> menus = adminMenuService.list();
        for (int i = 0; i < menus.size(); i++) {
            if (Objects.equals(0L, menus.get(i).getParentId())) {
                adminMenus.add(menus.get(i));
                for (AdminMenu menu : menus) {
                    if (Objects.equals(menu.getParentId(), menus.get(i).getMenuId())) {
                        adminMenus.add(menu);
                    }
                }
            }
        }
        //检查当前角色是否是项目管理员
        AdminUserBO adminUserBO = new AdminUserBO();
        AdminRole adminRole = adminRoleService.lambdaQuery().eq(AdminRole::getRoleType, 1).eq(AdminRole::getLabel, 2).one();
        if (ObjectUtil.isNotEmpty(adminRole)) {
            adminUserBO.setRoleId(adminRole.getRoleId());
            adminUserBO.setPageType(0);
            BasePage<AdminUserVO> basePage = adminUserService.queryUserList(adminUserBO);
            Boolean flag = false;
            for (AdminUserVO adminUserVO : basePage.getList()) {
                if (ObjectUtil.equal(adminUserVO.getUserId(), UserUtil.getUserId())) {
                    flag = true;
                }
            }
            if (!UserUtil.getSuperUser().equals(UserUtil.getUserId())) {
                if (!flag) {
                    adminMenus.removeIf(a -> "projectManger".equals(a.getRealm()));
                }
            }
        }

        JSONObject jsonObject = createMenu(new HashSet<>(adminMenus), 0L);
        List<AdminConfig> adminConfigList = adminConfigService.queryConfigListByName((Object[]) AdminModuleEnum.getValues());
        if (jsonObject.containsKey(AdminModuleEnum.CRM.getValue())) {
            jsonObject.remove(AdminModuleEnum.CRM.getValue());
        }

        if (jsonObject.containsKey(JXC)) {
            JSONObject jxc = jsonObject.getJSONObject(JXC);
            if (jxc.containsKey(BI) && !jxc.getJSONObject(BI).isEmpty()) {
                JSONObject jxcBi = jxc.getJSONObject(BI);
                jxc.remove(BI);
                if (jsonObject.containsKey(BI)) {
                    JSONObject bi = jsonObject.getJSONObject(BI);
                    bi.putAll(jxcBi);
                    jsonObject.put("bi", bi);
                } else {
                    jsonObject.put("bi", jxcBi);
                }
            } else if (jxc.isEmpty()) {
                jsonObject.remove(JXC);
            }
        }
        //判断当前用户是否有角色
        List<AdminUserRole> userRoles = adminUserRoleService.lambdaQuery().eq(AdminUserRole::getUserId, userId).list();
        if (userRoles.size() == 0) {
            jsonObject.put(AdminModuleEnum.OA.getValue(), new JSONObject());
        }

        //判断当前用户是否有角色

        if (!jsonObject.containsKey("project")) {
            jsonObject.put("project", new JSONObject());
        }


        if (UserUtil.isAdmin()) {
            //超级管理员如果没有项目管理员权限 自动增加
            if (!jsonObject.getJSONObject(AdminModuleEnum.MANAGE.getValue()).containsKey("projectManger")) {
                JSONObject systemManger = new JSONObject();
                systemManger.put("setRole", true);
                systemManger.put("setStatus", true);
                jsonObject.getJSONObject(AdminModuleEnum.MANAGE.getValue()).put("projectManger", systemManger);
            }

        }
        /*
          循环模块配置，把禁用的模块菜单隐藏掉
         */
        adminConfigList.forEach(adminConfig -> {
            //是否开启该模块
            Integer status = adminConfig.getStatus();
            //需要特殊处理的模块
            List<String> oaArray = Arrays.asList(AdminModuleEnum.TASK_EXAMINE.getValue(), AdminModuleEnum.LOG.getValue(), AdminModuleEnum.BOOK.getValue(), AdminModuleEnum.CALENDAR.getValue());
            if (oaArray.contains(adminConfig.getName())) {
                if (!jsonObject.containsKey(AdminModuleEnum.OA.getValue())) {
                    jsonObject.put(AdminModuleEnum.OA.getValue(), new JSONObject());
                }
                JSONObject object = jsonObject.getJSONObject(AdminModuleEnum.OA.getValue());
                if (status == 0) {
                    object.remove(adminConfig.getName());
                } else {
                    if (!AdminModuleEnum.BOOK.getValue().equals(adminConfig.getName())) {
                        object.put(adminConfig.getName(), new JSONObject());
                    }
                }
                return;
            }
            if (Objects.equals(0, adminConfig.getStatus())) {
                JSONObject object = jsonObject.getJSONObject(AdminModuleEnum.MANAGE.getValue());
                //禁用模块时，删除管理模块下对应
                if (object != null) {
                    object.remove(adminConfig.getName());
                    //判定后台管理下是否有crm权限配置
                    if (adminConfig.getName().equals(AdminModuleEnum.SCRM.getValue())&&object.containsKey(AdminModuleEnum.CRM.getValue())) {
                        //去除后台管理下企业微信配置
                        object.getJSONObject(AdminModuleEnum.CRM.getValue()).fluentRemove("wxConfig");
                    }
                }
                jsonObject.remove(adminConfig.getName());
                //处理crm里面与scrm相关的
                if (adminConfig.getName().equals(AdminModuleEnum.SCRM.getValue())) {
                    if (jsonObject.containsKey(AdminModuleEnum.CRM.getValue())) {
                        JSONObject crm = jsonObject.getJSONObject(AdminModuleEnum.CRM.getValue());
                        //关联scrm开关权限 关闭企微客户列表、员工会话、客户会话
                        crm.fluentRemove("staffConversation").fluentRemove("customerConversation");
                        if (crm.containsKey("customer")) {
                            crm.getJSONObject("customer").fluentRemove("scrmCustomer").fluentRemove("synchronous");
                        }
                    }

                }
            } else {
                if (!jsonObject.containsKey(adminConfig.getName())) {
                    jsonObject.put(adminConfig.getName(), new JSONObject());
                }
            }
        });
        if (jsonObject.containsKey(HRM) && jsonObject.getJSONObject(HRM).isEmpty() && !UserUtil.isAdmin()) {
            List<AdminRole> roles = queryRoleByRoleTypeAndUserId(9);
            Boolean isInHrm = hrmService.queryIsInHrm().getData();
            //不在人资员工并且人资没有角色不展示人资导航
            if (!isInHrm && CollUtil.isEmpty(roles)) {
                jsonObject.remove("hrm");
            }
        }
        //如果存在人资，暂时先移除绩效考核模块(升级）
        if (jsonObject.containsKey(CS)) {
            JSONObject cs = jsonObject.getJSONObject("cs");
            if (cs != null) {
                //在线客服模块只有设置为客服的人才能建立socket链接，超管不用充当客服，所以这里仅对是否含有客服角色的人员进行判断
                cs.remove("online");
                JSONObject customerService = new JSONObject();
                if (CollectionUtil.isNotEmpty(userRoles)) {
                    List<Long> roleIds = userRoles.stream().map(AdminUserRole::getRoleId).collect(Collectors.toList());
                    Integer count = adminMenuService.queryHasMenuAuthByByRoleIds(roleIds, 1305L);
                    if (count > 0) {
                        customerService.put("customerService", true);
                    } else {
                        customerService.put("customerService", false);
                    }
                } else {
                    customerService.put("customerService", false);
                }
                cs.put("online", customerService);
            }
        }
        //无jxc权限，隐藏
        if(jsonObject.containsKey(JXC)&&jsonObject.getJSONObject(JXC).isEmpty()){
            jsonObject.remove(JXC);
        }
        redis.setex(cacheKey, 300, jsonObject);
        return jsonObject;
    }


    /**
     * 查询用户所属权限
     *
     * @param userIds ids
     */
    @Override
    public void authInvalidate(List<Long> userIds) {
        if (userIds.isEmpty()) {
            return;
        }
        Object[] strings = userIds.stream().map(data -> AdminCacheKey.USER_AUTH_CACHE_KET + data).toArray(String[]::new);
        redis.del(strings);
    }

    /**
     * 通过用户ID查询角色列表
     *
     * @param userId 用户ID
     * @return data
     */
    @Override
    public List<AdminRole> queryRoleListByUserId(Long userId) {
        QueryWrapper<AdminUserRole> wrapper = new QueryWrapper<>();
        wrapper.select("role_id");
        wrapper.eq("user_id", userId);
        List<Long> roleIdList = adminUserRoleService.list(wrapper).stream().map(AdminUserRole::getRoleId).collect(Collectors.toList());
        if (roleIdList.size() > 0) {
            return listByIds(roleIdList);
        }
        return new ArrayList<>();
    }

    @Override
    public List<AdminRole> queryRoleListByUserId(List<Long> userIds) {
        QueryWrapper<AdminUserRole> wrapper = new QueryWrapper<>();
        wrapper.select("role_id");
        wrapper.in("user_id", userIds);
        List<Long> roleIdList = adminUserRoleService.list(wrapper).stream().map(AdminUserRole::getRoleId).collect(Collectors.toList());
        if (roleIdList.size() > 0) {
            roleIdList = roleIdList.stream().distinct().collect(Collectors.toList());
            return listByIds(roleIdList);
        }
        return new ArrayList<>();
    }

    @Override
    public Map<Long, List<AdminRole>> getByUserIds(List<Long> userIds) {
        List<AdminUserRole> userRoles = adminUserRoleService.lambdaQuery().in(AdminUserRole::getUserId, userIds).list();
        if (CollUtil.isEmpty(userRoles)) {
            return null;
        }
        List<Long> roleIds = userRoles.stream().map(AdminUserRole::getRoleId).collect(Collectors.toList());
        List<AdminRole> roles = lambdaQuery().in(AdminRole::getRoleId, roleIds).list();
        Map<Long, AdminRole> roleIdEntityMap = roles.stream().collect(Collectors.toMap(AdminRole::getRoleId, Function.identity()));
        Map<Long, List<AdminRole>> result = userRoles.stream().filter(r -> roleIdEntityMap.containsKey(r.getRoleId()))
                .collect(Collectors.groupingBy(AdminUserRole::getUserId, Collectors.mapping(m -> roleIdEntityMap.get(m.getRoleId()), Collectors.toList())));
        return result;
    }

    /**
     * 根据类型查询角色
     *
     * @param roleTypeEnum type
     * @return data
     */
    @Override
    public List<AdminRole> getRoleByType(AdminRoleTypeEnum roleTypeEnum) {
        List<AdminRole> recordList = lambdaQuery()
                .eq(AdminRole::getRoleType, roleTypeEnum.getType())
                .orderByAsc(AdminRole::getSorting)
                .list();
        String realm = roleTypeEnum.getName();
        LambdaQueryWrapper<AdminMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AdminMenu::getMenuId);
        wrapper.eq(AdminMenu::getParentId, 0L);
        wrapper.eq(AdminMenu::getRealm, realm);
        AdminMenu adminMenu = adminMenuService.getOne(wrapper);
        if (adminMenu != null) {
            Long pid = adminMenuService.getOne(wrapper).getMenuId();
            if (recordList.size() != 0) {
                recordList.forEach(record -> {
                    Map<String, List<Long>> map = new HashMap<>();
                    List<Long> data = getBaseMapper().getRoleMenu(pid, record.getRoleId());
                    //判断是否财务模块
                    if (ObjectUtil.notEqual(realm, AdminRoleTypeEnum.FINANCE.getName())) {
                        List<Long> bi = getBaseMapper().getRoleMenu(2L, record.getRoleId());
                        map.put("bi", bi);
                    }
                    map.put("data", data);
                    Map<String, String> keyMap = new HashMap<>();
                    keyMap.put("roleName_resourceKey", "rolesChild" + record.getRoleType() + "." + record.getRoleName());
                    record.setLanguageKeyMap(keyMap);
                    record.setRules(map);
                    if(DataAuthEnum.CUSTOM.getValue().equals(record.getDataType())){
                        List<AdminDataAuthDept> list = adminDataAuthDeptService.queryDeptByRoleId(record.getRoleId());
                        record.setDeptList(list);
                    }
                });
            }
        }
        return recordList;
    }


    /**
     * 根据类型查询角色
     *
     * @param roleTypeEnum type
     * @return data
     */
    @Override
    public List<AdminRole> getProjectRoleByType(AdminRoleTypeEnum roleTypeEnum, Long projectId) {
        List<AdminRole> recordList = lambdaQuery().eq(AdminRole::getRoleType, roleTypeEnum.getType())
                .list();
        String realm = roleTypeEnum.getName();
        LambdaQueryWrapper<AdminMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AdminMenu::getMenuId);
        wrapper.eq(AdminMenu::getParentId, 0L);
        wrapper.eq(AdminMenu::getRealm, realm);
        AdminMenu adminMenu = adminMenuService.getOne(wrapper);
        if (adminMenu != null) {
            Long pid = adminMenuService.getOne(wrapper).getMenuId();
            if (recordList.size() != 0) {
                recordList.forEach(record -> {
                    Map<String, List<Long>> map = new HashMap<>();
                    List<Long> data = getBaseMapper().getRoleMenu(pid, record.getRoleId());
                    //判断是否财务模块
                    if (ObjectUtil.notEqual(realm, AdminRoleTypeEnum.FINANCE.getName())) {
                        List<Long> bi = getBaseMapper().getRoleMenu(2L, record.getRoleId());
                        map.put("bi", bi);
                    }
                    map.put("data", data);
                    Map<String, String> keyMap = new HashMap<>();
                    keyMap.put("roleName_resourceKey", "rolesChild" + record.getRoleType() + "." + record.getRoleName());
                    record.setLanguageKeyMap(keyMap);
                    record.setRules(map);
                    if(DataAuthEnum.CUSTOM.getValue().equals(record.getDataType())){
                        List<AdminDataAuthDept> list = adminDataAuthDeptService.queryDeptByRoleId(record.getRoleId());
                        record.setDeptList(list);
                    }
                });
            }
        }
        return recordList;
    }

    @Override
    public List<AdminRole> getAllRoleMenu(List<AdminRole> recordList) {
        String realm = AdminRoleTypeEnum.parse(8).getName();
        LambdaQueryWrapper<AdminMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AdminMenu::getMenuId);
        wrapper.eq(AdminMenu::getParentId, 0L);
        wrapper.eq(AdminMenu::getRealm, realm);
        AdminMenu adminMenu = adminMenuService.getOne(wrapper);
        if (adminMenu != null) {
            Long pid = adminMenuService.getOne(wrapper).getMenuId();
            if (recordList.size() != 0) {
                recordList.forEach(record -> {
                    Map<String, List<Long>> map = new HashMap<>();
                    List<Long> data = getBaseMapper().getRoleMenu(pid, record.getRoleId());
                    map.put("data", data);
                    Map<String, String> keyMap = new HashMap<>();
                    keyMap.put("roleName_resourceKey", "rolesChild" + record.getRoleType() + "." + record.getRoleName());
                    record.setLanguageKeyMap(keyMap);
                    record.setRules(map);
                    if(DataAuthEnum.CUSTOM.getValue().equals(record.getDataType())){
                        List<AdminDataAuthDept> list = adminDataAuthDeptService.queryDeptByRoleId(record.getRoleId());
                        record.setDeptList(list);
                    }
                });
            }
        }
        return recordList;
    }

    /**
     * 查询全部角色
     *
     * @return data
     */
    @Override
    public List<AdminRoleVO> getAllRoleList() {
        List<AdminRoleVO> records = new ArrayList<>();
        List<AdminConfig> adminConfigs = configService.queryConfigListByName(AdminRoleTypeEnum.HRM.getName(), AdminRoleTypeEnum.FINANCE.getName());
        Map<String, List<AdminConfig>> adminMap = adminConfigs.stream().collect(Collectors.groupingBy(AdminConfig::getName));

        for (AdminRoleTypeEnum typeEnum : AdminRoleTypeEnum.values()) {
            // 20220221 wwl 修改 0, 3, 5, 8, 10 => 0, 3, 5, 8， 10为进销存
            if (Arrays.asList(0, 3, 8).contains(typeEnum.getType())) {
                continue;
            }
            if (!adminMap.containsKey(AdminRoleTypeEnum.HRM.getName()) || adminMap.get(AdminRoleTypeEnum.HRM.getName()).get(0).getStatus() == 0) {
                if (typeEnum.getType() == 9) {
                    continue;
                }
            }
            if (!adminMap.containsKey(AdminRoleTypeEnum.FINANCE.getName()) || adminMap.get(AdminRoleTypeEnum.FINANCE.getName()).get(0).getStatus() == 0) {
                if (typeEnum.getType() == 4) {
                    continue;
                }
            }
            AdminRoleVO record = new AdminRoleVO();
            record.setName(typeEnum.getDesc());
            record.setParentId(typeEnum.getType());
            List<AdminRole> recordList = getRoleByType(typeEnum);
            record.setList(recordList);
            Map<String, String> keyMap = new HashMap<>();
            keyMap.put("name_resourceKey", "menuRoles." + typeEnum.getType());
            record.setLanguageKeyMap(keyMap);
            records.add(record);
        }
        return records;
    }

    /**
     * 查询新增员工时的可查询角色
     *
     * @return 角色列表
     */
    @Override
    public List<AdminRoleVO> getRoleList() {
        List<AdminRoleVO> records = new ArrayList<>();
        boolean queryAllRole = adminRoleAuthService.isQueryAllRole();
        if (queryAllRole) {
            /* 可以查询全部直接走查询全部方法 */
            return getAllRoleList();
        }
        Set<Long> roleIds = adminRoleAuthService.queryAuthByUser();
        for (AdminRoleTypeEnum typeEnum : AdminRoleTypeEnum.values()) {
            AdminRoleVO record = new AdminRoleVO();
            record.setName(typeEnum.getDesc());
            record.setParentId(typeEnum.getType());
            List<AdminRole> recordList = getRoleByType(typeEnum);
            recordList.removeIf(adminRole -> !roleIds.contains(adminRole.getRoleId()));
            if (recordList.size() == 0) {
                continue;
            }
            record.setList(recordList);
            records.add(record);
        }
        return records;
    }

    @Override
    public Integer queryDataType(Long userId, Long menuId) {
        AdminRole adminRole = getBaseMapper().queryDataType(userId, menuId);
        if(adminRole != null){
            return adminRole.getDataType();
        }
        return null;
    }

    /**
     * 查询下属用户
     *
     * @param userId 用户ID
     * @param menuId 菜单ID
     * @return 权限
     */
    @Override
    public Collection<Long> queryUserByAuth(Long userId, Long menuId) {
        if (UserUtil.isAdmin()) {
            List<AdminUser> adminUsers = adminUserService.lambdaQuery().select(AdminUser::getUserId).list();
            return adminUsers.stream().map(AdminUser::getUserId).collect(Collectors.toList());
        }
        Integer dataType = queryDataType(userId, menuId);
        if (dataType == null) {
            return Collections.singletonList(0L);
        }
        Set<Long> userSet = new HashSet<>();
        if(!DataAuthEnum.CUSTOM.getValue().equals(dataType)){
            userSet.add(userId);
        }
        switch (DataAuthEnum.parse(dataType)) {
            case MYSELF: {
                return userSet;
            }
            case MYSELF_AND_SUBORDINATE: {

                List<Long> userIds = adminUserService.queryChildUserId(userId);

                userSet.addAll(userIds);
                break;
            }
            case THIS_DEPARTMENT: {
                AdminUser adminUser = adminUserService.getById(userId);

                List<Long> deptIds = new ArrayList<>();
                List<AdminSubsidiaryDept> subsidiaryDepts = adminSubsidiaryDeptService.lambdaQuery().eq(AdminSubsidiaryDept::getUserId, userId).list();

                if (CollectionUtil.isNotEmpty(subsidiaryDepts)) {
                    deptIds.addAll(subsidiaryDepts.stream().map(AdminSubsidiaryDept::getDeptId).collect(Collectors.toList()));
                }
                deptIds.add(adminUser.getDeptId());
                List<Long> userIds = adminUserService.queryUserByDeptIds(deptIds);
                userSet.addAll(userIds);
                break;
            }
            case THIS_DEPARTMENT_AND_SUBORDINATE: {
                AdminUser adminUser = adminUserService.getById(userId);

                List<Long> deptIds = adminDeptService.queryChildDept(adminUser.getDeptId());

                deptIds.add(adminUser.getDeptId());

                List<AdminSubsidiaryDept> subsidiaryDepts = adminSubsidiaryDeptService.lambdaQuery().eq(AdminSubsidiaryDept::getUserId, userId).list();

                if (CollectionUtil.isNotEmpty(subsidiaryDepts)) {
                    deptIds.addAll(subsidiaryDepts.stream().map(AdminSubsidiaryDept::getDeptId).collect(Collectors.toList()));
                }


                userSet.addAll(adminUserService.queryUserByDeptIds(deptIds));
                break;
            }
            case ALL: {
                List<AdminUser> adminUsers = adminUserService.lambdaQuery().select(AdminUser::getUserId).list();
                userSet.addAll(adminUsers.stream().map(AdminUser::getUserId).collect(Collectors.toSet()));
            }
            case CUSTOM: {
                List<Long> deptIds = adminRoleService.queryCustomDeptId(userId, menuId);
                List<Long> userIds = adminUserService.queryUserByDeptIds(deptIds);
                userSet.addAll(userIds);
            }
            default:
                break;
        }
        return userSet;
    }

    /**
     * 保存角色
     *
     * @param adminRole role
     */
    @Override
    public OperationLog add(AdminRole adminRole) {

        boolean exists = lambdaQuery().eq(AdminRole::getRoleName, adminRole.getRoleName()).eq(AdminRole::getRoleType, adminRole.getRoleType()).exists();
        if (exists) {
            throw new CrmException(AdminCodeEnum.ADMIN_ROLE_NAME_EXIST_ERROR);
        }
        OperationLog operationLog = new OperationLog();

        if (adminRole.getRoleId() != null) {
            AdminRole role = getById(adminRole.getRoleId());
            operationLog.setApplyObject(getOperateObjectByRoleType(role.getRoleType()));
            operationLog.setOperationObject(role.getRoleName());
            operationLog.setOperationInfo("将角色" + role.getRoleName() + "修改为" + adminRole.getRoleName());

            updateById(adminRole);
        } else {
            adminRole.setRoleId(null);
            adminRole.setStatus(1);
            adminRole.setRemark(null);
            save(adminRole);
            operationLog.setApplyObject(getOperateObjectByRoleType(adminRole.getRoleType()));
            operationLog.setOperationObject(adminRole.getRoleName());
            operationLog.setOperationInfo("新建角色" + adminRole.getRoleName());
        }
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog delete(Long roleId) {
        AdminRole adminRole = getById(roleId);
        if (CP.equals(adminRole.getRemark())) {
            throw new CrmException(AdminCodeEnum.ADMIN_DEFAULT_ROLE_CANNOT_BE_DELETED);
        }
        removeById(roleId);
        JSONObject object = new JSONObject().fluentPut("role_id", roleId);
        adminUserRoleService.removeByMap(object);
        adminRoleMenuService.removeByMap(object);
        adminDataAuthDeptService.lambdaUpdate().eq(AdminDataAuthDept::getRoleId, roleId).remove();
        OperateObjectEnum operateObjectByRoleType = getOperateObjectByRoleType(adminRole.getRoleType());
        OperationLog operationLog = new OperationLog();
        operationLog.setApplyObject(operateObjectByRoleType);
        operationLog.setApply(ApplyEnum.parse(operateObjectByRoleType.getApplyType()));
        operationLog.setOperationObject(adminRole.getRoleName());
        operationLog.setOperationInfo("删除角色" + adminRole.getRoleName());
        return operationLog;
    }

    /**
     * @return
     * @author zhangzhiwei
     * 复制
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public OperationLog copy(Long roleId) {
        AdminRole adminRole = getById(roleId);

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(adminRole.getRoleName());
        operationLog.setApplyObject(getOperateObjectByRoleType(adminRole.getRoleType()));
        LambdaQueryWrapper<AdminRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AdminRoleMenu::getMenuId);
        wrapper.eq(AdminRoleMenu::getRoleId, roleId);
        List<Long> menuIdsList = adminRoleMenuService.listObjs(wrapper, obj -> Convert.toLong(obj.toString()));
        String roleName = adminRole.getRoleName().trim();
        String pre = ReUtil.delFirst("[(]\\d+[)]$", roleName);
        List<AdminRole> adminRoleList;
        if (!ReUtil.contains(CANONICAL, roleName)) {
            adminRoleList = lambdaQuery().likeRight(AdminRole::getRoleName, pre).list();
        } else {
            adminRoleList = lambdaQuery().last(" role_name regexp '^[(]\\d+[)]$'").list();
        }
        StringBuilder numberSb = new StringBuilder();
        for (AdminRole dbAdminRole : adminRoleList) {
            String endCode = ReUtil.get("[(]\\d+[)]$", dbAdminRole.getRoleName(), 0);
            if (endCode != null) {
                numberSb.append(endCode);
            }
        }
        int i = 1;
        if (numberSb.length() != 0) {
            while (numberSb.toString().contains(LEFT_BRACKET + i + RIGHT_BRACKET)) {
                i++;
            }
        }
        adminRole.setRoleName(pre + "(" + i + ")");
        adminRole.setRoleId(null);
        adminRole.setRemark(null);
        save(adminRole);
        adminRoleMenuService.saveRoleMenu(adminRole.getRoleId(), menuIdsList);
        if (adminRole.getRoleType().equals(AdminRoleTypeEnum.MANAGER.getType()) && menuIdsList.contains(NUMBER)) {
            List<Long> authRoleIds = adminRoleAuthService.queryByRoleId(adminRole.getRoleId());
            adminRoleAuthService.saveRoleAuth(adminRole.getRoleId(), authRoleIds);
        }
        if(DataAuthEnum.CUSTOM.getValue().equals(adminRole.getDataType())){
            List<AdminDataAuthDept> list = adminDataAuthDeptService.lambdaQuery().eq(AdminDataAuthDept::getRoleId, roleId).list();
            adminDataAuthDeptService.saveDataAuthDept(list, adminRole.getRoleId());
        }
        operationLog.setOperationInfo("复制角色" + adminRole.getRoleName());
        return operationLog;
    }

    /**
     * 用户关联角色
     *
     * @param userIds 用户列表
     * @param roleIds 角色列表
     */
    @Override
    public List<OperationLog> relatedUser(List<Long> userIds, List<Long> roleIds) {
        if (CollUtil.isNotEmpty(roleIds)) {
            roleIds = roleIds.stream().distinct().collect(Collectors.toList());
            if (!adminRoleAuthService.isQueryAllRole()) {
                Set<Long> authByUser = adminRoleAuthService.queryAuthByUser();
                roleIds.retainAll(authByUser);
                if (roleIds.isEmpty()) {
                    throw new CrmException();
                }
            }
        } else {
            throw new CrmException(AdminCodeEnum.ADMIN_ROLE_NOT_EXIST_ERROR);
        }
        List<AdminUserRole> adminUserRoleList = new ArrayList<>();

        List<AdminRole> adminRoles = listByIds(roleIds);
        //转map,key为id,value为对象
        Map<Long, AdminRole> roleMap = adminRoles.stream().collect(Collectors.toMap(AdminRole::getRoleId, Function.identity()));


        List<OperationLog> operationLogs = new ArrayList<>();
        for (Long userId : userIds) {
            for (Long roleId : roleIds) {
                boolean exists = adminUserRoleService.lambdaQuery().eq(AdminUserRole::getRoleId, roleId).eq(AdminUserRole::getUserId, userId).exists();
                if (!exists) {
                    AdminUserRole userRole = new AdminUserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    adminUserRoleList.add(userRole);

                    AdminRole adminRole = roleMap.get(roleId);
                    OperateObjectEnum operateObjectByRoleType = getOperateObjectByRoleType(adminRole.getRoleType());
                    OperationLog operationLog = new OperationLog();
                    operationLog.setOperationObject(UserCacheUtil.getUserName(userId));
                    operationLog.setOperationInfo("为员工" + UserCacheUtil.getUserName(userId) + "关联" + adminRole.getRoleName());
                    operationLog.setApplyObject(operateObjectByRoleType);
                    operationLog.setApply(ApplyEnum.parse(operateObjectByRoleType.getApplyType()));
                    operationLogs.add(operationLog);
                }
            }
        }
        adminUserRoleService.saveBatch(adminUserRoleList, Const.BATCH_SAVE_SIZE);
        return operationLogs;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void accountUserRole(AdminUserRoleBO userRoleBO) {
        List<AdminUserRole> adminUserRoleList = new ArrayList<>();
        userRoleBO.getAuthSaveBOS().forEach(au -> {
            au.getRoleIdList().forEach(ro -> {
                AdminUserRole role = new AdminUserRole();
                role.setRoleId(ro);
                role.setUserId(au.getUserId());
                adminUserRoleList.add(role);
            });
            //先删除员工角色是财务类型根据员工id
            List<Long> ids = getBaseMapper().getUserRoleIds(AdminRoleTypeEnum.FINANCE.getType(), au.getUserId());
            adminUserRoleService.removeByIds(ids);
        });
        adminUserRoleService.saveBatch(adminUserRoleList, Const.BATCH_SAVE_SIZE);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<OperationLog> relatedDeptUser(List<Long> userIds, List<Long> deptIds, List<Long> roleIds) {
        Set<Long> userIdList = new HashSet<>();
        if (CollUtil.isNotEmpty(userIds)) {
            userIdList.addAll(userIds);
        }
        if (CollUtil.isNotEmpty(deptIds)) {
            List<Long> list = adminUserService.queryUserByDeptIds(deptIds);
            userIdList.addAll(list);
        }
        if (CollUtil.isEmpty(roleIds)) {
            throw new CrmException(AdminCodeEnum.ADMIN_ROLE_NOT_EXIST_ERROR);
        }
        roleIds = roleIds.stream().distinct().collect(Collectors.toList());
        List<AdminUserRole> adminUserRoleList = new ArrayList<>();

        List<OperationLog> operationLogList = new ArrayList<>();
        for (Long userId : userIdList) {
            if (Objects.equals(userId, UserUtil.getSuperUser())) {
                continue;
            }
            AdminUser user = adminUserService.getById(userId);
            OperationLog operationLog = new OperationLog();
            operationLog.setOperationObject(user.getUserId(), user.getRealname());
            operationLog.setOperationInfo("为员工" + user.getRealname() + "编辑角色");
            operationLogList.add(operationLog);

            adminUserRoleService.lambdaUpdate().eq(AdminUserRole::getUserId, userId).remove();
            for (Long roleId : roleIds) {
                AdminUserRole userRole = new AdminUserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                adminUserRoleList.add(userRole);
            }
        }

        boolean queryAllRole = adminRoleAuthService.isQueryAllRole();
        if (!queryAllRole) {
            Set<Long> authByUser = adminRoleAuthService.queryAuthByUser();
            adminUserRoleList.removeIf(userRole -> !authByUser.contains(userRole.getRoleId()));
        }
        adminUserRoleService.saveBatch(adminUserRoleList, Const.BATCH_SAVE_SIZE);

        return operationLogList;
    }

    private static final String ADMIN = "admin";

    /**
     * 取消用户关联角色
     *
     * @param userId 用户ID
     * @param roleId 角色ID
     * @return
     */
    @Override
    public OperationLog unbindingUser(Long userId, Long roleId) {
        boolean exists = adminUserRoleService.lambdaQuery().eq(AdminUserRole::getUserId, userId).ne(AdminUserRole::getRoleId, roleId).exists();
        if (!exists) {
            throw new CrmException(AdminCodeEnum.ADMIN_USER_NEEDS_AT_LEAST_ONE_ROLE);
        }
        AdminRole adminRole = getById(roleId);


        AdminUser adminUser = adminUserService.getById(userId);
        adminUserRoleService.lambdaUpdate().eq(AdminUserRole::getRoleId, roleId).eq(AdminUserRole::getUserId, userId).remove();

        OperateObjectEnum operateObjectByRoleType = getOperateObjectByRoleType(adminRole.getRoleType());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(adminUser.getRealname());
        operationLog.setOperationInfo("删除" + adminUser.getRealname() + "的" + adminRole.getRoleName());
        operationLog.setApplyObject(operateObjectByRoleType);
        operationLog.setApply(ApplyEnum.parse(operateObjectByRoleType.getApplyType()));
        return operationLog;
    }

    /**
     * 修改角色菜单关系
     *
     * @param adminRole adminrole
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public OperationLog updateRoleMenu(AdminRole adminRole) {
        AdminRole role = getById(adminRole.getRoleId());

        OperateObjectEnum operateObjectEnum = getOperateObjectByRoleType(role.getRoleType());

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(role.getRoleName());
        operationLog.setApplyObject(operateObjectEnum);
        operationLog.setOperationInfo("修改" + role.getRoleName() + "授权信息");
        operationLog.setApply(ApplyEnum.parse(operateObjectEnum.getApplyType()));
        updateById(adminRole);
        // 自定义数据权限
        if(DataAuthEnum.CUSTOM.getValue().equals(role.getDataType())){
            adminDataAuthDeptService.lambdaUpdate().eq(AdminDataAuthDept::getRoleId, role.getRoleId()).remove();
        }
        if(DataAuthEnum.CUSTOM.getValue().equals(adminRole.getDataType())){
            adminDataAuthDeptService.saveDataAuthDept(adminRole.getDeptList(), adminRole.getRoleId());
        }
        adminRoleMenuService.removeByMap(Collections.singletonMap("role_id", adminRole.getRoleId()));
        adminRoleMenuService.saveRoleMenu(adminRole.getRoleId(), adminRole.getMenuIds());
        return operationLog;
    }

    /**
     * 查询项目管理的角色
     *
     * @param label label
     * @return roleId
     */
    @Override
    public Long queryWorkRole(Integer label) {
        LambdaQueryWrapper<AdminRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AdminRole::getRoleId);
        if (label == null) {
            wrapper.eq(AdminRole::getRemark, "project");
        } else {
            wrapper.eq(AdminRole::getLabel, label);
        }
        AdminRole adminRole = getOne(wrapper);
        return adminRole != null ? adminRole.getRoleId() : null;
    }

    /**
     * 保存项目管理角色
     *
     * @param object obj
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setWorkRole(JSONObject object) {
        Long roleId = object.getLong("roleId");
        String roleName = object.getString("roleName");
        String remark = object.getString("remark");
        JSONArray menuIds = object.getJSONArray("menuIds");
        AdminRole adminRole;
        if (roleId == null) {
            adminRole = new AdminRole();
            adminRole.setRoleName(roleName);
            adminRole.setRemark(remark);
            adminRole.setRoleType(6);
            save(adminRole);
        } else {
            adminRole = getById(roleId);
            adminRole.setRoleName(roleName);
            adminRole.setRemark(remark);
            adminRole.setRoleId(roleId);
            updateById(adminRole);
            adminRoleMenuService.removeByMap(new JSONObject().fluentPut("role_id", roleId));
        }
        adminRoleMenuService.saveRoleMenu(adminRole.getRoleId(), menuIds.toJavaList(Long.class));
    }

    /**
     * 删除项目管理角色
     *
     * @param roleId roleId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteWorkRole(Long roleId) {
        removeById(roleId);
        adminRoleMenuService.removeByMap(new JSONObject().fluentPut("role_id", roleId));
        getBaseMapper().deleteWorkRole(queryWorkRole(3), roleId);
    }


    private JSONObject createMenu(Set<AdminMenu> adminMenuList, Long parentId) {
        JSONObject jsonObject = new JSONObject();
        adminMenuList.forEach(adminMenu -> {
            if (Objects.equals(parentId, adminMenu.getParentId())) {
                if (Objects.equals(1, adminMenu.getMenuType())) {
                    JSONObject object = createMenu(adminMenuList, adminMenu.getMenuId());
                    if (!object.isEmpty()) {
                        jsonObject.put(adminMenu.getRealm(), object);
                    }
                } else {
                    jsonObject.put(adminMenu.getRealm(), Boolean.TRUE);
                }
            }
        });
        return jsonObject;
    }

    @Override
    public List<AdminRole> queryRoleList() {
        return lambdaQuery().eq(AdminRole::getStatus, 1).in(AdminRole::getRoleType, Arrays.asList(5, 6)).list();

    }

    @Override
    public AdminRole queryDefaultRole() {
        List<AdminRole> list = lambdaQuery().eq(AdminRole::getRoleName, "默认角色").eq(AdminRole::getRemark, "cp").list();
        Map<String, String> keymap = new HashMap<>();
        keymap.put("roleName_resourceKey", "rolesChild1.默认角色");
        if (list.isEmpty()) {
            Long userId = UserUtil.getUserId();
            LocalDateTime dateTime = LocalDateTime.now();
            AdminRole adminRole = new AdminRole(BaseUtil.getNextId(), "默认角色", 1, "cp", 1, 2, 1, 5, userId, userId, dateTime, dateTime);
            save(adminRole);
            adminRoleMenuService.saveRoleMenu(adminRole.getRoleId(), AdminConst.ROLE_MENU_LIST_8);
            adminRole.setLanguageKeyMap(keymap);
            return adminRole;
        }
        return list.get(0).setLanguageKeyMap(keymap);
    }

    @Override
    public List<String> queryNoAuthMenu(Long userId) {
        if (UserUtil.isAdmin()) {
            return Collections.emptyList();
        }
        AdminUser userInfo = adminUserService.getById(userId);
        List<String> noAuthMenuUrls = new ArrayList<>();

        List<AdminMenu> adminMenus = adminMenuService.queryMenuList(userId);

        if (adminMenus.isEmpty()) {
            noAuthMenuUrls.add("/*/**");
            return noAuthMenuUrls;
        }
        List<Long> menuIdList = adminMenus.stream().map(AdminMenu::getMenuId).collect(Collectors.toList());
        LambdaQueryWrapper<AdminMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.isNotNull(AdminMenu::getRealmUrl);

        List<AdminMenu> menuList = adminMenuService.list(lambdaQueryWrapper);

        List<AdminMenu> noAuthMenus = menuList.stream().filter(e -> !menuIdList.contains(e.getMenuId())).collect(Collectors.toList());

        if (!noAuthMenus.isEmpty()) {
            List<String> collect = noAuthMenus.stream().map(AdminMenu::getRealmUrl).collect(Collectors.toList());
            for (String s : collect) {
                if (s.contains(",")) {
                    noAuthMenuUrls.addAll(Arrays.asList(s.split(",")));
                } else {
                    noAuthMenuUrls.add(s);
                }
            }
        }

        List<AdminMenu> hasMenus = menuList.stream().filter(e -> menuIdList.contains(e.getMenuId())).collect(Collectors.toList());

        List<String> hasMenuUrls = new ArrayList<>();
        for (AdminMenu hasMenu : hasMenus) {
            if (hasMenu.getRealmUrl().contains(",")) {
                hasMenuUrls.addAll(Arrays.asList(hasMenu.getRealmUrl().split(",")));
            } else {
                hasMenuUrls.add(hasMenu.getRealmUrl());
            }
        }
        Collection<String> intersection = CollUtil.intersection(noAuthMenuUrls, hasMenuUrls);

        noAuthMenuUrls.removeAll(intersection);
        return noAuthMenuUrls;
    }

    @Override
    public List<AdminRole> queryRoleByRoleTypeAndUserId(Integer type) {
        return getBaseMapper().queryRoleByRoleTypeAndUserId(type, UserUtil.getUserId());
    }

    /**
     * 跟进角色ID查询下属员工
     *
     * @param roleIds 角色ID
     * @return userIds
     */
    @Override
    public List<Long> queryUserIdByRoleId(List<Long> roleIds) {
        LambdaQueryChainWrapper<AdminUserRole> queryChainWrapper = adminUserRoleService.lambdaQuery().select(AdminUserRole::getUserId).in(AdminUserRole::getRoleId, roleIds);
        return queryChainWrapper.list().stream().map(AdminUserRole::getUserId).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delUserRole(Long userId) {
        //先删除员工角色是财务类型根据员工id
        List<Long> ids = getBaseMapper().getUserRoleIds(AdminRoleTypeEnum.FINANCE.getType(), userId);
        adminUserRoleService.removeByIds(ids);
    }

    @Override
    public List<Map<String, Object>> listByRoleId(List<Long> roleIds) {
        List<AdminRole> adminRoles = lambdaQuery()
                .select(AdminRole::getRoleId, AdminRole::getRoleName)
                .in(AdminRole::getRoleId, roleIds).list();
        return adminRoles.stream().map(a -> {
            Map<String, Object> role = new HashMap<>(2);
            role.put("roleId", a.getRoleId());
            role.put("roleName", a.getRoleName());
            return role;
        }).collect(Collectors.toList());
    }

    @Override
    public JSONObject addProjectRole(AdminRole adminRole) {
        List<Long> adminRoleMenuIds = adminRole.getMenuIds();
        String remark = adminRole.getRemark();
        boolean exists = lambdaQuery().eq(AdminRole::getRoleName, adminRole.getRoleName()).eq(AdminRole::getRoleType, adminRole.getRoleType()).exists();
        if (exists) {
            throw new CrmException(AdminCodeEnum.ADMIN_ROLE_NAME_EXIST_ERROR);
        }
        if (adminRole.getRoleId() != null) {
            updateById(adminRole);
        } else {
            adminRole.setRoleId(null);
            adminRole.setStatus(1);
            adminRole.setRemark(null);
            save(adminRole);
        }
        adminRole.setRemark(remark);
        adminRole.setMenuIds(adminRoleMenuIds);
        this.updateRoleMenu(adminRole);

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(adminRole.getRoleName());
        operationLog.setOperationInfo("新建自定义角色：" + adminRole.getRoleName());

        JSONObject data = new JSONObject();
        data.put("role", adminRole);
        data.put("operationLog", operationLog);
        return data;
    }

    @Override
    public AdminRole queryRoleId( String remark) {
        return getBaseMapper().queryRoleId( remark);
    }


    @Override
    public void addRelatedDept(List<Long> deptIds, List<Long> roleIds) {
        if (CollUtil.isNotEmpty(roleIds)) {
            roleIds = roleIds.stream().distinct().collect(Collectors.toList());
            if (!adminRoleAuthService.isQueryAllRole()) {
                Set<Long> authByUser = adminRoleAuthService.queryAuthByUser();
                roleIds.retainAll(authByUser);
                if (roleIds.size() == 0) {
                    return;
                }
            }
        } else {
            throw new CrmException(AdminCodeEnum.ADMIN_ROLE_NOT_EXIST_ERROR);
        }
        List<AdminDeptRole> deptRoleList = new ArrayList<>();
        for (Long deptId : deptIds) {
            for (Long roleId : roleIds) {
                boolean exists = adminDeptRoleService.lambdaQuery().eq(AdminDeptRole::getRoleId, roleId).eq(AdminDeptRole::getDeptId, deptId).exists();
                if (!exists) {
                    AdminDeptRole deptRole = new AdminDeptRole();
                    deptRole.setDeptId(deptId);
                    deptRole.setRoleId(roleId);
                    deptRoleList.add(deptRole);
                }
            }
        }
        adminDeptRoleService.saveBatch(deptRoleList, Const.BATCH_SAVE_SIZE);
    }


    @Override
    public void updateRelatedDept(List<Long> deptIds, List<Long> roleIds) {
        if (CollUtil.isNotEmpty(roleIds)) {
            roleIds = roleIds.stream().distinct().collect(Collectors.toList());
            if (!adminRoleAuthService.isQueryAllRole()) {
                Set<Long> authByUser = adminRoleAuthService.queryAuthByUser();
                roleIds.retainAll(authByUser);
                if (roleIds.size() == 0) {
                    return;
                }
            }
        } else {
            throw new CrmException(AdminCodeEnum.ADMIN_ROLE_NOT_EXIST_ERROR);
        }
        List<AdminDeptRole> deptRoleList = new ArrayList<>();

        for (Long deptId : deptIds) {
            adminDeptRoleService.lambdaUpdate().eq(AdminDeptRole::getDeptId, deptId).remove();
            for (Long roleId : roleIds) {
                AdminDeptRole deptRole = new AdminDeptRole();
                deptRole.setDeptId(deptId);
                deptRole.setRoleId(roleId);
                deptRoleList.add(deptRole);
            }
        }
        adminDeptRoleService.saveBatch(deptRoleList, Const.BATCH_SAVE_SIZE);
    }

    @Override
    public void unbindingDept(Long deptId, Long roleId) {
        boolean exists = adminDeptRoleService.lambdaQuery().eq(AdminDeptRole::getDeptId, deptId).ne(AdminDeptRole::getRoleId, roleId).exists();
        if (!exists) {
            throw new CrmException(AdminCodeEnum.ADMIN_USER_NEEDS_AT_LEAST_ONE_ROLE);
        }
        adminDeptRoleService.lambdaUpdate().eq(AdminDeptRole::getRoleId, roleId).eq(AdminDeptRole::getDeptId, deptId).remove();
    }

    /**
     * 获取WP管理角色权限
     *
     * @return
     */
    @Override
    public JSONObject wpAuth() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.fluentPut(WP, false);
        return jsonObject;
    }

    @Override
    public List<Long> queryCustomDeptId(Long userId, Long menuId) {
        AdminRole adminRole = getBaseMapper().queryDataType(userId, menuId);
        if(adminRole != null){
            List<Long> deptList = new ArrayList<>();
            List<AdminDataAuthDept> list = adminDataAuthDeptService.lambdaQuery().eq(AdminDataAuthDept::getRoleId, adminRole.getRoleId()).list();
            for (AdminDataAuthDept adminDataAuthDept : list) {
                deptList.add(adminDataAuthDept.getDeptId());
                if(Objects.equals(adminRole.getIsNeedChild(), 1)){
                    List<Long> deptIds = adminDeptService.queryChildDept(adminDataAuthDept.getDeptId());
                    deptList.addAll(deptIds);
                }
            }
            return deptList;
        }
        return Collections.emptyList();
    }


    public OperateObjectEnum getOperateObjectByRoleType(Integer roleType) {
        switch (roleType) {
            case 1:
                return OperateObjectEnum.SYSTEM_MANAGEMENT_ROLE;
            case 2:
                return OperateObjectEnum.CUSTOMER_MANAGEMENT_ROLE;
            case 4:
                return OperateObjectEnum.FINANCIAL_MANAGEMENT_ROLE;
            case 7:
                return OperateObjectEnum.OA_MANAGEMENT_ROLE;
            case 8:
                return OperateObjectEnum.CUSTOM_ROLE;
            case 9:
                return OperateObjectEnum.HRM_MANAGEMENT_ROLE;
            case 10:
                return OperateObjectEnum.JXC_MANAGEMENT_ROLE;
            case 13:
                return OperateObjectEnum.MARKETING_MANAGEMENT_ROLE;
        }
        return OperateObjectEnum.NULL;
    }


    @Override
    public Set<Long> queryUserCustomDeptId(Long userId, Long menuId) {
        List<AdminRole> roleList = getBaseMapper().queryDataTypeList(userId, menuId);
        if(roleList != null && !roleList.isEmpty()){
            Set<Long> deptSet = new HashSet<>();
            List<Long> roleIdList = roleList.stream().map(AdminRole::getRoleId).collect(Collectors.toList());
            Map<Long, AdminRole> roleMap = roleList.stream().collect(Collectors.toMap(AdminRole::getRoleId, Function.identity(), (v1, v2) -> v2));
            List<AdminDataAuthDept> authDeptList = adminDataAuthDeptService.lambdaQuery().in(AdminDataAuthDept::getRoleId, roleIdList).list();
            //全部部门
            List<AdminDept> list = adminDeptService.lambdaQuery().list();
            Map<Long, List<AdminDept>> deptGroup =new HashMap<>();
            if (list != null && !list.isEmpty()){
                deptGroup = list.stream().collect(Collectors.groupingBy(AdminDept::getParentId));
            }
            for (AdminDataAuthDept adminDataAuthDept : authDeptList) {
                deptSet.add(adminDataAuthDept.getDeptId());
                AdminRole adminRole = roleMap.get(adminDataAuthDept.getRoleId());
                if(Objects.equals(adminRole.getIsNeedChild(), 1)){
                    getChildrenDeptId(deptGroup ,adminDataAuthDept.getDeptId(), deptSet);
                }
            }
            return deptSet;
        }
        return new HashSet<>();
    }

    @Override
    public List<Integer> queryDataTypeList(Long userId, Long menuId) {
        List<AdminRole> roleList = getBaseMapper().queryDataTypeList(userId, menuId);
        if(roleList != null && !roleList.isEmpty()){
            return roleList.stream().map(AdminRole::getDataType).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    private Set<Long> getChildrenDeptId(Map<Long, List<AdminDept>> deptGroup, Long deptId, Set<Long> result) {
        if (deptGroup.containsKey(deptId)) {
            List<AdminDept> deptList = deptGroup.get(deptId);
            if (!deptList.isEmpty()) {
                for (AdminDept dept : deptList) {
                    result.add(dept.getDeptId());
                    getChildrenDeptId(deptGroup, dept.getDeptId(), result);
                }
            }
        }
        return result;
    }
}
